<?php
/****************************************************************************
* Product: PHP extension script for HSLAB HTTP Monitor
* First release: October 29, 2010
* Developed by: Handy Software Lab / apache-monitor.com
* Copyright: (c) 2010-2012 Handy Software Lab. All rights reserved.
* Notes:
* 1. You permitted to use this script only with HSLAB HTTP Monitor;
* 2. You can modify this script (do not change the output data formats) to ensure it is working with your operating system.
* 3. Please send us your modified script to include it in distribution package: helpdesk.hs-lab.com or join to
*    https://code.google.com/p/hslab-http-monitor-php-extension-script/

* Requirements:
* This module uses the functions of В» zlib by Jean-loup Gailly and Mark Adler.
* You have to use a zlib version >= 1.0.9 with this module.
* ZLIB PHP extension
* http://us3.php.net/manual/en/book.zlib.php
* PHP 4 >= 4.0.1, PHP 5

****************************************************************************/

// classes

/* Zip file creation class. Creates zip files on the fly...
use the functions add_dir() and add_file() to build the zip file;
see example code below
by Eric Mueller
http://www.themepark.com
http://www.devco.net/archives/2005/05/24/creating_zip_files_with_php.php

v1.1 9-20-01
  - added comments to example
v1.0 2-5-01
initial version with:
  - class appearance
  - add_file() and file() methods
  - gzcompress() output hacking
by Denis O.Philippov, webmaster@atlant.ru, http://www.atlant.ru
*/
// official ZIP file format: http://www.pkware.com/appnote.txt

class zipfile
{

    var $datasec = array(); // array to store compressed data
    var $ctrl_dir = array(); // central directory
    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
    var $old_offset = 0;

    function add_dir($name)

    // adds "directory" to archive - do this before putting any files in directory!
    // $name - name of directory... like this: "path/"
    // ...then you can add files using add_file with names like "path/file.txt"
    {
        $name = str_replace("\\", "/", $name);

        $fr = "\x50\x4b\x03\x04";
        $fr .= "\x0a\x00";    // ver needed to extract
        $fr .= "\x00\x00";    // gen purpose bit flag
        $fr .= "\x00\x00";    // compression method
        $fr .= "\x00\x00\x00\x00"; // last mod time and date

        $fr .= pack("V",0); // crc32
        $fr .= pack("V",0); //compressed filesize
        $fr .= pack("V",0); //uncompressed filesize
        $fr .= pack("v", strlen($name) ); //length of pathname
        $fr .= pack("v", 0 ); //extra field length
        $fr .= $name;
        // end of "local file header" segment

        // no "file data" segment for path

        // "data descriptor" segment (optional but necessary if archive is not served as file)
        $fr .= pack("V",$crc); //crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize

        // add this entry to array
        $this -> datasec[] = $fr;

        $new_offset = strlen(implode("", $this->datasec));

        // ext. file attributes mirrors MS-DOS directory attr byte, detailed
        // at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp

        // now add to central record
        $cdrec = "\x50\x4b\x01\x02";
        $cdrec .="\x00\x00";    // version made by
        $cdrec .="\x0a\x00";    // version needed to extract
        $cdrec .="\x00\x00";    // gen purpose bit flag
        $cdrec .="\x00\x00";    // compression method
        $cdrec .="\x00\x00\x00\x00"; // last mod time & date
        $cdrec .= pack("V",0); // crc32
        $cdrec .= pack("V",0); //compressed filesize
        $cdrec .= pack("V",0); //uncompressed filesize
        $cdrec .= pack("v", strlen($name) ); //length of filename
        $cdrec .= pack("v", 0 ); //extra field length
        $cdrec .= pack("v", 0 ); //file comment length
        $cdrec .= pack("v", 0 ); //disk number start
        $cdrec .= pack("v", 0 ); //internal file attributes
        $ext = "\x00\x00\x10\x00";
        $ext = "\xff\xff\xff\xff";
        $cdrec .= pack("V", 16 ); //external file attributes  - 'directory' bit set

        $cdrec .= pack("V", $this -> old_offset ); //relative offset of local header
        $this -> old_offset = $new_offset;

        $cdrec .= $name;
        // optional extra field, file comment goes here
        // save to array
        $this -> ctrl_dir[] = $cdrec;
    }

    function add_file($data, $name)

    // adds "file" to archive
    // $data - file contents
    // $name - name of file in archive. Add path if your want

    {
        $name = str_replace("\\", "/", $name);
        //$name = str_replace("\\", "\\\\", $name);

        $fr = "\x50\x4b\x03\x04";
        $fr .= "\x14\x00";    // ver needed to extract
        $fr .= "\x00\x00";    // gen purpose bit flag
        $fr .= "\x08\x00";    // compression method
        $fr .= "\x00\x00\x00\x00"; // last mod time and date

        $unc_len = strlen($data);
        $crc = crc32($data);
        $zdata = gzcompress($data);
        $zdata = substr( substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
        $c_len = strlen($zdata);
        $fr .= pack("V",$crc); // crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize
        $fr .= pack("v", strlen($name) ); //length of filename
        $fr .= pack("v", 0 ); //extra field length
        $fr .= $name;
        // end of "local file header" segment

        // "file data" segment
        $fr .= $zdata;

        // "data descriptor" segment (optional but necessary if archive is not served as file)
        $fr .= pack("V",$crc); //crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize

        // add this entry to array
        $this -> datasec[] = $fr;

        $new_offset = strlen(implode("", $this->datasec));

        // now add to central directory record
        $cdrec = "\x50\x4b\x01\x02";
        $cdrec .="\x00\x00";    // version made by
        $cdrec .="\x14\x00";    // version needed to extract
        $cdrec .="\x00\x00";    // gen purpose bit flag
        $cdrec .="\x08\x00";    // compression method
        $cdrec .="\x00\x00\x00\x00"; // last mod time & date
        $cdrec .= pack("V",$crc); // crc32
        $cdrec .= pack("V",$c_len); //compressed filesize
        $cdrec .= pack("V",$unc_len); //uncompressed filesize
        $cdrec .= pack("v", strlen($name) ); //length of filename
        $cdrec .= pack("v", 0 ); //extra field length
        $cdrec .= pack("v", 0 ); //file comment length
        $cdrec .= pack("v", 0 ); //disk number start
        $cdrec .= pack("v", 0 ); //internal file attributes
        $cdrec .= pack("V", 32 ); //external file attributes - 'archive' bit set

        $cdrec .= pack("V", $this -> old_offset ); //relative offset of local header
//        echo "old offset is ".$this->old_offset.", new offset is $new_offset<br>";
        $this -> old_offset = $new_offset;

        $cdrec .= $name;
        // optional extra field, file comment goes here
        // save to central directory
        $this -> ctrl_dir[] = $cdrec;
    }

    function file() { // dump out file
        $data = implode("", $this -> datasec);
        $ctrldir = implode("", $this -> ctrl_dir);

        return
            $data.
            $ctrldir.
            $this -> eof_ctrl_dir.
            pack("v", sizeof($this -> ctrl_dir)).     // total # of entries "on this disk"
            pack("v", sizeof($this -> ctrl_dir)).     // total # of entries overall
            pack("V", strlen($ctrldir)).             // size of central dir
            pack("V", strlen($data)).                 // offset to start of central dir
            "\x00\x00";                             // .zip file comment length
    }
}
?>
<?php
// !!!! Please DO NOT MODIFY this section manually! All variables are maintained by the
// HSLAB HTTP Monitor extension script generator.
//---script definitions start
////---pwd---
define(PWD,"12345");
////---pwd---
////---software---
define(SOFTWARE,"HSLAB HTTP Monitor PHP extension script");
////---software---
////---vendor---
define(VENDOR,'(c) Handy Software Lab, All Rights Reserved. <a href="http://apache-monitor.com" target="_blank">HSLAB HTTP Monitor Home</a>');
////---vendor---
////---version---
define(VERSION,"1.16.1025.2011");
////---version---
////---ipcheck---
$allowed_ips = array("10.0.0","192.168.0.","93.73.29.");
////---ipcheck---
//---script definitions end

$client_ip = $_SERVER['REMOTE_ADDR'];

$zipped_output_string = "";
$zipped_output = 0;
?>
<?php
// functions

function _GetParam($Name, $Default = "")
{
    if ( isset($_GET[$Name]) )
      return $_GET[$Name];
    else if ( isset($_POST[$Name]) )
      return $_POST[$Name];
    else
      return $Default;
}

function SmartOutput($output_string)
{
  global $zipped_output_string;
  global $zipped_output;

  if($zipped_output == 1)
     $zipped_output_string .= $output_string;
  if($zipped_output == 0)
     echo $output_string;

}

function RemotePageContent( $url ,$page_max_size = 1000000)
{
	$ch      = curl_init( $url );

	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);	// return web page
	curl_setopt($ch, CURLOPT_HEADER, false);		// don't return headers
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);	// follow redirects
	curl_setopt($ch, CURLOPT_ENCODING, "");			// handle all encodings
	curl_setopt($ch, CURLOPT_USERAGENT, "spider");	// who am i
	curl_setopt($ch, CURLOPT_AUTOREFERER, true);	// set referer on redirect
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);	// timeout on connect
	curl_setopt($ch, CURLOPT_TIMEOUT, 120);			// timeout on response
	curl_setopt($ch, CURLOPT_MAXREDIRS, 10);		// stop after 10 redirects

    //curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    //$errmsg  = curl_error( $ch );
    //$header  = curl_getinfo( $ch );
    curl_close( $ch );

    //$header['errno']   = $err;
    // $header['errmsg']  = $errmsg;
    //$header['content'] = $content;
    //print($header[0]);
    return $content;
}

function GetOS($print = 1)
{
$command = "uname -s";
$output = shell_exec($command);
$system = $output;
$OS = "";
$OS_FAMILY = "";

    if(preg_match("#Linux#i",$output))
    {
        $OS = "Linux";
        $OS_FAMILY = "Linux";
    }
    if(preg_match("#FreeBSD#i",$output))
    {
        $OS = "FreeBSD";
        $OS_FAMILY = "BSD";
    }
    if(preg_match("#OpenBSD#i",$output))
    {
        $OS = "OpenBSD";
        $OS_FAMILY = "BSD";
    }
    if(preg_match("#NetBSD#i",$output))
    {
        $OS = "NetBSD";
        $OS_FAMILY = "BSD";
    }
    if(preg_match("#IRIX64#i",$output))
    {
        $OS = "IRIX64";
        $OS_FAMILY = "IRIX";
    }
    if(preg_match("#SunOS#i",$output))
    {
        $OS = "Solaris";
        $OS_FAMILY = "SunOS";
    }
    if(preg_match("#Darwin#i",$output))
    {
        $OS = "Mac OS X";
        $OS_FAMILY = "Mac OS";
    }
    if(preg_match("#AIX#i",$output))
    {
        $OS = "IBM AIX";
        $OS_FAMILY = "AIX";
    }
    if(preg_match("#DragonFly#i",$output))
    {
        $OS = "DragonFlyBSD";
        $OS_FAMILY = "BSD";
    }

    if($print)
    {
        //parser regexpr "--OS--<pre>(.*)</pre>--OS--"
        SmartOutput("--OS--<pre>$OS</pre>--OS--</br>");
        SmartOutput("--OSFAMILY--<pre>$OS_FAMILY</pre>--OSFAMILY--</br>");
        SmartOutput("\n");
        SmartOutput("[OS]\n");
        SmartOutput("os=$OS\n");
        SmartOutput("os_family=$OS_FAMILY\n");
    }

return $OS_FAMILY;
}

function GetSysStats($OS_FAMILY)
{
    //parser regexpr "--SYSSTATS--<pre>(.*)</pre>--SYSSTATS--"
    $command = "top -b -u bin -n1";
    $output = shell_exec($command);
    SmartOutput("--SYSSTATS--<pre>$output</pre>--SYSSTATS--</br>");
}

function GetApacheProcesses($OS_FAMILY)
{
    if($OS_FAMILY = "BSD")
    {
 	    $command = "top -b -n 10000 | grep httpd";
    }
    if($OS_FAMILY = "Linux")
    {
	    $command = "top -b -n 1 | grep httpd";
    }
    $output = shell_exec($command);
    SmartOutput("--APACHEPROCESSES--<pre>$output</pre>--APACHEPROCESSES--</br>");
}

function GetApacheConf($print = 1)
{
    $command = "locate httpd.conf | grep /etc/.*/httpd\.conf$";
    $output = shell_exec($command);
    $lines = explode("\n", $output);
    $apache_conf = $lines[0];
    $apache_conf1 = $lines[1];
    if($print)
    {
        SmartOutput("--APACHECONF--<pre>$apache_conf</pre>--APACHECONF--<pre>$apache_conf1</pre>--APACHECONF--</br>");
        SmartOutput("[APACHE_CONF]\n");
        SmartOutput("conf=$apache_conf\n");
    }

return $apache_conf;
}

function GetModStatus($apache_conf)
{
    $command = 'cat '.$apache_conf.' | grep .*LoadModule.*status_module';
    $output = shell_exec($command);
    SmartOutput("--MODSTATUS--<pre>".$output."</pre>--MODSTATUS--</br>");
    $output = trim($output);
    if($output[0] != '#')
       $mod_status_loaded = 1;

    $command = 'cat '.$apache_conf.' | grep ^ExtendedStatus ';
    $output = shell_exec($command);
    SmartOutput("--EXTENDEDSTATUS--<pre>".$output."</pre>--EXTENDEDSTATUS--</br>");
    $lines = explode(" ", $output);

    $extended_status_on = 0;
    if(strpos($lines[1], "On") === FALSE)
       $extended_status_on = 0;
    else
       $extended_status_on = 1;


    SmartOutput("[APACHE_STATUS]\n");
    SmartOutput("mod_status_loaded=$mod_status_loaded\n");
    SmartOutput("extended_status_on=$extended_status_on\n");

return $extended_status_on;
}

function GetMaxClients($apache_conf)
{
    $command = 'cat '.$apache_conf.' | grep ^MaxClients.*[0-9]';
    $output = shell_exec($command);
    $lines = explode("MaxClients", $output);
    SmartOutput("--APACHEMAXCLIENTS--<pre>".$output."</pre>--APACHEMAXCLIENTS--</br>");
    $max_clients = 0;
    foreach ($lines as $str)
    {
		$str = trim($str);
		if(!empty($str))
		{
			$max_clients = $str;
			break;
		}
    }

    SmartOutput("\n");
    SmartOutput("[APACHE_MAX_CLIENTS]\n");
    SmartOutput("max_clients=$max_clients\n");

return $max_clients;
}

function GetServerStatusHandler($apache_conf)
{
$server_status_handler = 0;
$command = 'cat '.$apache_conf.' | grep "<Location /server-status>"';
//echo "command = ".$command."</br>";
    $output = shell_exec($command);
    SmartOutput("--SERVERSTATUSHANDLER--<pre>".$output."</pre>--SERVERSTATUSHANDLER--</br>");

    if($output[0] == '<')
       $server_status_handler = 1;

    SmartOutput("\n");
    SmartOutput("[APACHE_SERVER_STATUS_HANDLER]\n");
    SmartOutput("server_status_handler=$server_status_handler\n");

return $server_status_handler;
}

function GetScriptVersion()
{
    SmartOutput("--SCRIPT_VERSION--<pre>".VERSION."</pre>--SCRIPT_VERSION--</br>");
    SmartOutput("\n");
    SmartOutput("[SCRIPT_VERSION]\n");
    SmartOutput("script_version=".VERSION."\n");
}

function GetServerStatus($server_status_uri = "")
{
//parameter is a full url: http://mydomain.com/server-status
$url = "http://localhost/server-status";
if(!empty($server_status_uri))
  $url = "http://localhost".$server_status_uri;

$page = RemotePageContent( $url );
SmartOutput("--SERVERSTATUS--<pre>$page</pre>--SERVERSTATUS--</br>");
}

function PrintTimeStamp()
{
    SmartOutput("\n");
    $timenow = time();
    SmartOutput("Created ".date("r",$timenow)." by the ".SOFTWARE.". ".VENDOR);
    SmartOutput("\n");
}

//---------- Main script body ----------
$pwd = _GetParam("pwd");
$ver = _GetParam("ver");
$sv = _GetParam("sv");
$ignore_script_version = _GetParam("iv",0);
$GetOS = _GetParam("GetOS");
$GetSysStats = _GetParam("GetSysStats");
$GetApacheProcesses = _GetParam("GetApacheProcesses");
$GetApacheConf = _GetParam("GetApacheConf");
$GetModStatus = _GetParam("GetModStatus");
$GetMaxClients = _GetParam("GetMaxClients");
$GetServerStatusHandler = _GetParam("GetServerStatusHandler");
$GetModStatusEx = _GetParam("GetModStatusEx");
$GetMaxClientsEx = _GetParam("GetMaxClientsEx");
$GetServerStatusHandlerEx = _GetParam("GetServerStatusHandlerEx");
$httpd_conf = _GetParam("httpd_conf");
$GetScriptVersion = _GetParam("GetScriptVersion");
$GetServerStatus = _GetParam("GetServerStatus");
$server_status_uri = _GetParam("ssurl","");//default is /server-status
$zipped_output = _GetParam("zip",0);

    header("Content-type: text/html; charset=UTF-8");
    header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past


//----------- Begin script output -----------

if (!extension_loaded('zlib') && $zipped_output) {
    if (!dl('zlib.so')) { //Try to load a PHP extension at runtime
        echo "Zip PHP extension is not available!<br/>";
        echo "You can't use \"Zipped output\" option.<br/>";
        echo "Please install and enable Zip PHP extension.<br/>";
        echo 'Please read here for details: <a href="http://us3.php.net/manual/en/book.zlib.php">http://us3.php.net/manual/en/book.zlib.php.</a><br/>';
        PrintTimeStamp();
        exit;
    }
}

if($zipped_output != 1)
{
//    SmartOutput('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
//    SmartOutput('<html xmlns="http://www.w3.org/1999/xhtml">');
//    SmartOutput('<head>');
//    SmartOutput('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />');
//    SmartOutput('<title>'.SOFTWARE.'</title>');
//    SmartOutput('</head>');
//    SmartOutput('<body>');
}

SmartOutput(SOFTWARE.'</br>');
SmartOutput('Version '.VERSION.'</br>');
SmartOutput(VENDOR.'</br>');
SmartOutput("</br>\n");

//compare script and software versions to avoid wrong results
if(strcmp(VERSION , $sv) && !$ignore_script_version)
{
    $msg = "Warning: script version (".VERSION.") and HSLAB HTTP Monitor </br>software version (".$sv.") are different!</br>Script may produce wrong results. Please, update the script!";
    SmartOutput("--WARNING--<pre>\n1\n</pre>--WARNING--</br>\n");
    SmartOutput("--WARNINGDESCRIPTION--<pre>\n$msg\n</pre>--WARNINGDESCRIPTION--</br>");
}

$pwd_ok = 0;
$client_ok = 0;
//--- security checks ---
//password
if(defined ('PWD'))
{
  if(strcmp($pwd , PWD) == 0)
     $pwd_ok = 1;
  else
     $pwd_ok = 0;
}
else
  $pwd_ok = 1;

//ip
if(isset($allowed_ips))
{
	foreach($allowed_ips as $ip)
	{
		if(stristr($client_ip,$ip) === FALSE)
			continue;
		else
		{
			$client_ok = 1;
		}
	}
}
else
	$client_ok = 1;

//--- security checks ---

if($pwd_ok && $client_ok)
{//security check passed
if(isset($GetOS) && $GetOS)
	GetOS();
if(isset($GetSysStats) && $GetSysStats)
	GetSysStats(GetOS(0));
if(isset($GetApacheProcesses) && $GetApacheProcesses)
	GetApacheProcesses(GetOS(0));
if(isset($GetApacheConf) && $GetApacheConf)
	GetApacheConf();
if(isset($GetModStatus) && $GetModStatus)
	GetModStatus(GetApacheConf(0));
if(isset($GetMaxClients) && $GetMaxClients)
	GetMaxClients(GetApacheConf(0));
if(isset($GetServerStatusHandler) && $GetServerStatusHandler)
	GetServerStatusHandler(GetApacheConf(0));

if(isset($GetModStatusEx) && $GetModStatusEx)
	GetModStatus($httpd_conf);
if(isset($GetMaxClientsEx) && $GetMaxClientsEx)
	GetMaxClients($httpd_conf);
if(isset($GetServerStatusHandlerEx) && $GetServerStatusHandlerEx)
	GetServerStatusHandler($httpd_conf);

if(isset($GetScriptVersion) && $GetScriptVersion)
	GetScriptVersion();

if(isset($GetServerStatus) && $GetServerStatus)
	GetServerStatus($server_status_uri);



PrintTimeStamp();
}
else
{
//security check failed

SmartOutput("--ERROR--<pre>\n1\n</pre>--ERROR--</br>");

if(!$pwd_ok)
   SmartOutput("--ERRORDESCRIPTION--<pre>\nAutorization failed. Please check your password.\n</pre>--ERRORDESCRIPTION--</br>");
if(!$client_ok)
   SmartOutput("--ERRORDESCRIPTION--<pre>\nAccess control failed. You not allowed to access this script from ".$client_ip.".\n</pre>--ERRORDESCRIPTION--</br>");

PrintTimeStamp();
}


 if($zipped_output == 1)
 {

    $zipfile = new zipfile();
    $zipfile->add_file($zipped_output_string, "output");

    header("Pragma: public"); // required
    header("Expires: 0");
    //header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
    header("Cache-Control: private",false); // required for certain browsers
    header('Content-Type: application/zip');
    header('Content-Length: ' . filesize($file));
    header('Content-Disposition: attachment; filename="ext-out.zip"');

    echo $zipfile->file();
}
else
{
//SmartOutput('</body>');
//SmartOutput('</html>');
}
?>